﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using CH.Reia.Infrastructure.Repository;
using CH.Reia.Infrastructure.Data;
using CH.Reia.Infrastructure.Entity;

namespace CH.Reia.Repository
{
    public sealed class Repository<T> : IRepository<T>, IDisposable
    {
        private readonly DataBase dataBase;

        private Repository(DataBase dataContext)
        {
            this.dataBase = dataContext;
        }

        public static Repository<T> CreateRepository()
        {
            var dataBase = DataBase.CreateDataBase(ConfigurationManager.ConnectionStrings["ReiaDataBase"].ToString());

            return new Repository<T>(dataBase);
        }

        #region IRepository<T> Members

        public List<T> Load(T loadEntity)
        {
            var tLoaded = new List<T>();

            tLoaded.Add((T)this.dataBase.EntityLoad(loadEntity));

            return (tLoaded);
        }

        public List<DataRow> DatabaseInformation(T informationEntity)
        {
            var listFind = new List<DataRow>();

            this.dataBase.DatabaseInformation(informationEntity).ForEach(q => listFind.Add((DataRow)q));

            return listFind;
        }

        public Boolean DatabaseDelete(String tableName)
        {
            return this.dataBase.DatabaseDelete(tableName);
        }

        public List<T> List(T listEntity)
        {
            return this.Find(listEntity);
        }

        public List<T> Save(T saveEntity)
        {
            var tSaved = new List<T>();

            if (this.dataBase.EntitySave(saveEntity as IEntity))
                tSaved.Add(saveEntity);

            return tSaved;
        }

        public List<T> Update(T updateEntity)
        {
            var tUpadated = new List<T>();

            if (this.dataBase.EntityUpdate(updateEntity as IEntity))
                tUpadated.Add(updateEntity);

            return tUpadated;
        }

        public List<T> Delete(T deleteEntity)
        {
            var tDeleted = new List<T>();

            if (this.dataBase.EntityDelete(deleteEntity as IEntity))
                tDeleted.Add(deleteEntity);

            return tDeleted;
        }

        public List<T> Find(T findEntity)
        {
            var listFind = new List<T>();

            this.dataBase.EntityFind(findEntity).ForEach(q => listFind.Add((T)LazyLoading.Builder((T)q as IEntity, this.dataBase)));

            return listFind;
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            if (this.dataBase != null)
            {
                this.dataBase.Dispose();
            }
        }

        #endregion
    }
}
